package com.cunfang.util;

import java.io.IOException;
import java.security.MessageDigest;
import java.util.ArrayList;
import java.util.List;
import java.util.TimerTask;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.cunfang.entity.PageData;

public final class CONNECTOR {

	/* 存储token的list */
	private static List<PageData> LISTTOKEN = new ArrayList<PageData>();

	/**
	 * @功能：获得(生成) token字符串(传入fduration token保存的时长 单位：秒)
	 * @作者：RC
	 * @日期：2016-03-21
	 * */
	public final static String GETCURTOKEN(long fduration, String value) {
		long lo = System.currentTimeMillis();
		final String token = ENCRYPT(lo + ""); /* 加密 */
		// System.out.println("token：" + token);
		/** 超出100000个 将不再存储token **/
		if (LISTTOKEN.size() > 100000) {
			return token + "_error";
		}

		/* 存入token */
		AddToken(token, value);

		/* 设置 过期时间 */
		final java.util.Timer timer = new java.util.Timer();
		timer.schedule(new TimerTask() {

			@Override
			public void run() {
				/* 移除token */
				RemoveToken(token);

				/* 停止计时器 */
				timer.cancel();
			}

		}, fduration * 1000, 60 * 1 * 1000);

		return token;
	}

	/**
	 * @功能：验证token
	 * @作者：RC
	 * @日期：2016-03-21
	 * */
	public final static boolean VERIFYTOKEN(HttpServletRequest httpRequest,
			HttpServletResponse httpResponse) throws IOException {
		/* 第一： token存放在header中 */
		String token = httpRequest.getHeader("token");
		if (token == null || "null".equals(token)) {
			/* 第二：token存放在url参数中 */
			token = httpRequest.getParameter("token");
		}
		String result = "{\"status\":400, \"msg\":\"token参数不存在\"}";
		if (ContainsToken(token)) {
			return true;
		} else {
			result = "{\"status\":401, \"msg\":\"token参数不合法，请重新请登录\"}";
		}
		/* 防止字符乱码 */
		httpResponse.setCharacterEncoding("UTF-8");
		httpResponse.setContentType("text/html");
		httpResponse.getWriter().write(result);
		return false;
	}

	/**
	 * @功能：算法加密
	 * @作者：RC
	 * @日期：2016-03-21
	 * */
	private static String ENCRYPT(String s) {
		char hexDigits[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
				'A', 'B', 'C', 'D', 'E', 'F' };
		try {
			byte[] btInput = s.getBytes();
			/* 获得MD5摘要算法的 MessageDigest 对象 */
			MessageDigest mdInst = MessageDigest.getInstance("MD5");
			/* 使用指定的字节更新摘要 */
			mdInst.update(btInput);
			/* 获得密文 */
			byte[] md = mdInst.digest();
			/* 把密文转换成十六进制的字符串形式 */
			int j = md.length;
			char str[] = new char[j * 2];
			int k = 0;
			for (int i = 0; i < j; i++) {
				byte byte0 = md[i];
				str[k++] = hexDigits[byte0 >>> 4 & 0xf];
				str[k++] = hexDigits[byte0 & 0xf];
			}
			return new String(str);
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	/**
	 * @功能：移除token
	 * @作者：RC
	 * @日期：2016-11-03
	 * */
	public static void RemoveToken(String token) {
		PageData pd = null;
		for (int i = 0; i < LISTTOKEN.size(); i++) {
			pd = LISTTOKEN.get(i);
			if (pd.containsKey(token)) {
				LISTTOKEN.remove(pd);
				
			}
		}
	}

	/**
	 * @功能：添加token
	 * @作者：RC
	 * @日期：2016-11-03
	 * */
	private static void AddToken(String token, String value) {
		PageData pd = null;
		for (int i = 0; i < LISTTOKEN.size(); i++) {
			pd = LISTTOKEN.get(i);
			/** 多人使用同一个账号... **/
			// if (pd.containsValue(value)) {
			// LISTTOKEN.remove(pd);
			// }
		}
		pd = new PageData();
		pd.put(token, value);
		LISTTOKEN.add(pd);
	}

	/**
	 * @功能：token是否存在
	 * @作者：RC
	 * @日期：2016-11-03
	 * */
	private static boolean ContainsToken(String token) {
		PageData pd = null;
		for (int i = 0; i < LISTTOKEN.size(); i++) {
			pd = LISTTOKEN.get(i);
			if (pd.containsKey(token)) {
				return true;
			}
		}
		return false;
	}

	/**
	 * @功能：根据token得到Value
	 * @作者：RC
	 * @日期：2016-11-03
	 * */
	public static String GetTokenValue(String token) {
		PageData pd = null;
		for (int i = 0; i < LISTTOKEN.size(); i++) {
			pd = LISTTOKEN.get(i);
			if (pd.containsKey(token)) {
				return pd.getString(token);
			}
		}
		return null;
	}
}
